package org.example.java.util.concurrency.thread.condition;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ThreadTest2 {
  static class Business {
    private boolean bool = true;
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public /*synchronized*/ void main(int loop) throws InterruptedException {
      lock.lock();
      try {
        while (bool) {
          System.out.println(Thread.currentThread().getName() + " loop await before");
          condition.await();//this.wait();
          System.out.println(Thread.currentThread().getName() + " loop await end");
        }
        for (int i = 0; i < 10; i++) {
          System.out.println("main thread seq of " + i + ", loop of " + loop);
        }
        bool = true;
        condition.signal();//this.notify();
      } finally {
        lock.unlock();
      }
    }

    public /*synchronized*/ void sub(int loop) throws InterruptedException {
      lock.lock();
      try {
        while (!bool) {
          System.out.println(Thread.currentThread().getName() + " loop await before");
          condition.await();//this.wait();
          System.out.println(Thread.currentThread().getName() + " loop await end");
        }
        for (int i = 0; i < 10; i++) {
          System.out.println("sub thread seq of " + i + ", loop of " + loop);
        }
        bool = false;
        condition.signal();//this.notify();
      } finally {
        lock.unlock();
      }
    }
  }

  public static void main(String[] args) {
    final Business business = new Business();
    new Thread(new Runnable() {
      @Override
      public void run() {
        threadExecute(business, "sub");
      }
    }).start();
    threadExecute(business, "main");
  }

  public static void threadExecute(Business business, String threadType) {
    for (int i = 0; i < 10; i++) {
      try {
        if ("main".equals(threadType)) {
          business.main(i);
        } else {
          business.sub(i);
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }
}


